package com.southminority.ethnic.service.contact.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.southminority.ethnic.common.exception.BusinessException;
import com.southminority.ethnic.common.result.PageResult;
import com.southminority.ethnic.mapper.contact.ContactMapper;
import com.southminority.ethnic.pojo.Contact;
import com.southminority.ethnic.service.contact.ContactService;
import com.southminority.ethnic.controller.contact.vo.ContactVO;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 联系留言服务实现类
 * 
 * @author SouthMinority
 */
@Slf4j
@Service
@Transactional
public class ContactServiceImpl implements ContactService {

    private final ContactMapper contactMapper;

    // 联系类型映射
    private static final Map<String, String> CONTACT_TYPE_DISPLAY_MAP = new HashMap<>();
    static {
        CONTACT_TYPE_DISPLAY_MAP.put("inquiry", "咨询");
        CONTACT_TYPE_DISPLAY_MAP.put("cooperation", "合作");
        CONTACT_TYPE_DISPLAY_MAP.put("suggestion", "建议");
        CONTACT_TYPE_DISPLAY_MAP.put("complaint", "投诉");
        CONTACT_TYPE_DISPLAY_MAP.put("other", "其他");
    }

    // 联系类型选项
    private static final List<String> CONTACT_TYPE_OPTIONS = Arrays.asList(
            "咨询", "合作", "建议", "投诉", "其他"
    );

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public ContactServiceImpl(ContactMapper contactMapper) {
        this.contactMapper = contactMapper;
    }

    // ==================== 前端接口实现 ====================

    @Override
    public ContactVO submitContact(ContactVO contactVO, HttpServletRequest request) {
        if (contactVO == null) {
            throw new BusinessException("联系信息不能为空");
        }

        // 验证必填字段
        if (!StringUtils.hasText(contactVO.getName())) {
            throw new BusinessException("姓名不能为空");
        }
        if (!StringUtils.hasText(contactVO.getMessage())) {
            throw new BusinessException("留言内容不能为空");
        }

        // 验证邮箱或电话至少填写一个
        if (!StringUtils.hasText(contactVO.getEmail()) && !StringUtils.hasText(contactVO.getPhone())) {
            throw new BusinessException("邮箱或电话至少填写一个");
        }

        Contact contact = new Contact();
        BeanUtils.copyProperties(contactVO, contact);

        // 获取IP地址和User-Agent
        if (request != null) {
            String ipAddress = getClientIpAddress(request);
            String userAgent = request.getHeader("User-Agent");
            contact.setIpAddress(ipAddress);
            contact.setUserAgent(userAgent);
        }

        // 设置默认值
        contact.setStatus(0); // 待处理
        contact.setCreateTime(LocalDateTime.now());
        contact.setUpdateTime(LocalDateTime.now());

        int result = contactMapper.insert(contact);
        if (result <= 0) {
            throw new BusinessException("提交联系表单失败");
        }

        log.info("用户提交联系表单成功: ID={}, 姓名={}, 主题={}", contact.getId(), contact.getName(), contact.getSubject());
        
        return getContactById(contact.getId());
    }

    @Override
    @Transactional(readOnly = true)
    public List<String> getContactTypeList() {
        return CONTACT_TYPE_OPTIONS;
    }

    // ==================== 管理端接口实现 ====================

    @Override
    @Transactional(readOnly = true)
    public PageResult<ContactVO> getContactPage(Long current, Long size, String keyword, String contactType, Integer status) {
        // 创建分页对象
        Page<Contact> page = new Page<>(current, size);
        
        // 构建查询条件
        QueryWrapper<Contact> wrapper = new QueryWrapper<>();
        
        // 关键词搜索（姓名、主题、留言内容）
        if (StringUtils.hasText(keyword)) {
            wrapper.and(qw -> qw.like("name", keyword)
                              .or().like("subject", keyword)
                              .or().like("message", keyword));
        }
        
        // 联系类型筛选
        if (StringUtils.hasText(contactType)) {
            wrapper.eq("contact_type", contactType);
        }
        
        // 状态筛选
        if (status != null) {
            wrapper.eq("status", status);
        } else {
            wrapper.ne("status", -1); // 默认不显示已删除的
        }
        
        // 排序：待处理优先，然后按创建时间倒序
        wrapper.orderByAsc("status").orderByDesc("create_time");
        
        // 执行分页查询
        IPage<Contact> pageResult = contactMapper.selectPage(page, wrapper);
        
        // 转换为VO并构建分页结果
        List<ContactVO> voList = pageResult.getRecords().stream()
                                          .map(this::convertToVO)
                                          .collect(Collectors.toList());
        
        return PageResult.<ContactVO>builder()
                .current(pageResult.getCurrent())
                .size(pageResult.getSize())
                .total(pageResult.getTotal())
                .pages(pageResult.getPages())
                .records(voList)
                .build();
    }

    @Override
    @Transactional(readOnly = true)
    public List<ContactVO> getAllContactList() {
        QueryWrapper<Contact> wrapper = new QueryWrapper<>();
        wrapper.ne("status", -1)
               .orderByAsc("status")
               .orderByDesc("create_time");
        
        List<Contact> contactList = contactMapper.selectList(wrapper);
        return contactList.stream()
                         .map(this::convertToVO)
                         .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public ContactVO getContactById(Long id) {
        if (id == null) {
            throw new BusinessException("联系ID不能为空");
        }

        Contact contact = contactMapper.selectById(id);
        if (contact == null) {
            throw new BusinessException("联系记录不存在");
        }

        return convertToVO(contact);
    }

    @Override
    public Boolean updateContactStatus(Long id, Integer status) {
        if (id == null) {
            throw new BusinessException("联系ID不能为空");
        }
        if (status == null) {
            throw new BusinessException("状态值不能为空");
        }

        Contact contact = contactMapper.selectById(id);
        if (contact == null) {
            throw new BusinessException("联系记录不存在");
        }

        contact.setStatus(status);
        contact.setUpdateTime(LocalDateTime.now());
        
        int result = contactMapper.updateById(contact);
        if (result > 0) {
            log.info("更新联系留言状态成功: ID={}, Status={}", id, status);
        }
        
        return result > 0;
    }

    @Override
    public Boolean replyContact(Long id, String replyContent, Long replyUserId) {
        if (id == null) {
            throw new BusinessException("联系ID不能为空");
        }
        if (!StringUtils.hasText(replyContent)) {
            throw new BusinessException("回复内容不能为空");
        }

        Contact contact = contactMapper.selectById(id);
        if (contact == null) {
            throw new BusinessException("联系记录不存在");
        }

        contact.setReplyContent(replyContent);
        contact.setReplyTime(LocalDateTime.now());
        contact.setReplyUserId(replyUserId);
        contact.setStatus(2); // 已回复
        contact.setUpdateTime(LocalDateTime.now());
        
        int result = contactMapper.updateById(contact);
        if (result > 0) {
            log.info("回复联系留言成功: ID={}, ReplyUserId={}", id, replyUserId);
        }
        
        return result > 0;
    }

    @Override
    public Boolean deleteContact(Long id) {
        if (id == null) {
            throw new BusinessException("联系ID不能为空");
        }

        Contact contact = contactMapper.selectById(id);
        if (contact == null) {
            throw new BusinessException("联系记录不存在");
        }

        // 软删除
        contact.setStatus(-1);
        contact.setUpdateTime(LocalDateTime.now());
        
        int result = contactMapper.updateById(contact);
        if (result > 0) {
            log.info("删除联系留言成功: ID={}", id);
        }
        
        return result > 0;
    }

    @Override
    public Boolean batchDeleteContact(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("联系ID列表不能为空");
        }

        List<Contact> contactList = contactMapper.selectBatchIds(ids);
        if (contactList.isEmpty()) {
            throw new BusinessException("未找到要删除的联系记录");
        }

        // 批量软删除
        LocalDateTime now = LocalDateTime.now();
        contactList.forEach(contact -> {
            contact.setStatus(-1);
            contact.setUpdateTime(now);
        });

        int updatedCount = 0;
        for (Contact contact : contactList) {
            updatedCount += contactMapper.updateById(contact);
        }

        if (updatedCount > 0) {
            log.info("批量删除联系留言成功: 删除数量={}", updatedCount);
        }

        return updatedCount == contactList.size();
    }

    @Override
    @Transactional(readOnly = true)
    public Long getPendingContactCount() {
        QueryWrapper<Contact> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 0); // 待处理
        
        return contactMapper.selectCount(wrapper);
    }

    @Override
    @Transactional(readOnly = true)
    public List<ContactVO> getLatestContactList(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        QueryWrapper<Contact> wrapper = new QueryWrapper<>();
        wrapper.ne("status", -1)
               .orderByDesc("create_time")
               .last("LIMIT " + limit);
        
        List<Contact> contactList = contactMapper.selectList(wrapper);
        return contactList.stream()
                         .map(this::convertToVO)
                         .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<ContactVO> getContactTypeStatistics() {
        // TODO: 实现联系类型统计功能
        // 这里可以通过原生SQL或聚合查询实现
        return Arrays.asList();
    }

    // ==================== 私有方法 ====================

    /**
     * 转换为VO对象
     */
    private ContactVO convertToVO(Contact contact) {
        ContactVO vo = new ContactVO();
        BeanUtils.copyProperties(contact, vo);
        
        // 联系类型显示名称
        vo.setContactTypeDisplay(CONTACT_TYPE_DISPLAY_MAP.getOrDefault(contact.getContactType(), contact.getContactType()));
        
        // 状态显示
        vo.setStatusDisplay(getStatusDisplay(contact.getStatus()));
        
        // 是否已回复
        vo.setHasReply(StringUtils.hasText(contact.getReplyContent()));
        
        // 时间格式化
        if (contact.getCreateTime() != null) {
            vo.setCreateTimeStr(contact.getCreateTime().format(DATE_FORMATTER));
        }
        if (contact.getReplyTime() != null) {
            vo.setReplyTimeStr(contact.getReplyTime().format(DATE_FORMATTER));
        }
        
        return vo;
    }

    /**
     * 获取状态显示文本
     */
    private String getStatusDisplay(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 0: return "待处理";
            case 1: return "已处理";
            case 2: return "已回复";
            case -1: return "已删除";
            default: return "未知";
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (StringUtils.hasText(xForwardedFor) && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0];
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (StringUtils.hasText(xRealIp) && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
} 